use clap::Parser;

use serialport::{DataBits, FlowControl, Parity, SerialPortBuilder, StopBits};

use super::port;

#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Args {
    // 列出串口设备
    #[arg(long, conflicts_with_all = ["device", "baud_rate", "data_bits", "stop_bits", "parity", "flow_control"])]
    list: bool,

    // 连接串口属性
    #[arg(short = 'D', long)]
    device: Option<String>,

    #[arg(short = 'B', long, default_value_t = 115200, help = "baud_rate")]
    baud_rate: u32,

    #[arg(long, default_value = "8", value_parser = ["5", "6", "7", "8"],  help = "data_bits")]
    data_bits: String,

    #[arg(long, default_value = "1", value_parser = ["1", "2"] ,  help = "stop_bits")]
    stop_bits: String,

    #[arg(long, default_value = "none", value_parser = ["none", "odd", "even"], help = "parity")]
    parity: String,

    #[arg(long, default_value = "none",
                value_parser = ["none", "software", "hardware"],
                help = "flow_control")]
    flow_control: String,
}

pub fn generate_builder() -> Result<SerialPortBuilder, String> {
    let args = Args::parse();

    if args.list {
        let _serial_data = port::list_serial_info(serialport::SerialPortType::PciPort).unwrap();
        let _usb_data = port::list_usb_info().unwrap();
        println!("{:?}", _serial_data);
        println!("{:?}", _usb_data);
        return Err("列表搜索完成".to_owned());
    }

    let device = match &args.device {
        Some(device) => device,
        None => return Err("必须提供 --device 参数来连接到串口设备".to_owned()),
    };

    // let baud_rate = match &args.baud_rate {
    //     Some(baud_rate) => baud_rate,
    //     None => return Err("必须提供 --baud_rate 参数来连接到串口设备".to_owned()),
    // };

    let data_bits = match args.data_bits.as_str() {
        "5" => DataBits::Five,
        "6" => DataBits::Six,
        "7" => DataBits::Seven,
        "8" => DataBits::Eight,
        _ => unreachable!(),
    };

    let stop_bits = match args.stop_bits.as_str() {
        "1" => StopBits::One,
        "2" => StopBits::Two,
        _ => unreachable!(),
    };

    let parity = match args.parity.as_str() {
        "none" => Parity::None,
        "odd" => Parity::Odd,
        "even" => Parity::Even,
        _ => unreachable!(),
    };
    let flow_control = match args.flow_control.as_str() {
        "none" => FlowControl::None,
        "software" => FlowControl::Software,
        "hardware" => FlowControl::Hardware,
        _ => unreachable!(),
    };

    let builder = serialport::new(device, args.baud_rate)
        .data_bits(data_bits)
        .stop_bits(stop_bits)
        .parity(parity)
        .flow_control(flow_control);

    Ok(builder)
}
